package com.pi.shisan.service.impl;

import com.pi.shisan.service.service.VolumeSettingService;
import com.pi.shisan.service.util.SingleThreadCreator;
import com.pi.shisan.util.FileUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 树莓派音量调节器
 */
@Service
@Slf4j
public class VolumeSettingServiceImpl implements VolumeSettingService {

    private Pattern pattern = Pattern.compile("\\[\\d+%\\]");

    private volatile int sysVolume = 4;

    @PostConstruct
    public void init() {
        try {
            sysVolume = this.getVolume();
        } catch (Exception e) {
            log.error("获取系统音量失败：",e);
        }
    }

    @Override
    public Integer getVolume() throws Exception{
        int volume = getVolumeAsPercent();
        return (int)((volume - 50) / (50/9D));
    }

    @Override
    public void setVolume(Integer num) throws Exception{
        justSetVolume(num);
        sysVolume = num;
    }

    @Override
    public void resetVolume() throws Exception {
        justSetVolume(sysVolume);
    }

    @Override
    public void justSetVolume(Integer num) throws Exception {
        SingleThreadCreator.getVolumeTran().execute(()->{
            int volume;
            try {
                volume = getVolumeAsPercent();
            } catch (Exception e) {
                return;
            }
            int target = calcVal(num);
            if (volume == target) {
                return;
            }
            int t = volume > target ? -1 : 1;
            while (true) {
                volume += t;
                try {
                    Process process = Runtime.getRuntime().exec("amixer set PCM "+ volume + "%");
                    process.waitFor();
                } catch (Exception e) {
                }
                if (t < 0) {
                    if (volume <= target) {
                        break;
                    }
                } else {
                    if (volume >= target) {
                        break;
                    }
                }
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                }
            }
        });
    }

    /**
     * 将0 - 9 转为百分比
     * @param num
     * @return
     */
    private int calcVal(int num) {
        //num 0 - 9
        //0 静音
        //计算取值 0 -> 0
        //1 - 9 -> 50 + 50 / 9 * num
        double val;
        if (num <= 0) {
            val = 0;
        } else {
            if (num > 9) {
                num = 9;
            }
            val = 50 + 50/9D*num;
        }
        if (val > 0) {
            if (val > (int)val) {
                val++;
            }
        }
        if (val > 100) {
            val = 100;
        }
        return (int)val;
    }

    /**
     * 获取系统的百分比音量
     * @return
     * @throws Exception
     */
    public int getVolumeAsPercent() throws Exception{
        Process process = Runtime.getRuntime().exec("amixer get PCM");
        process.waitFor();
        InputStream inputStream = process.getInputStream();
        Integer volume = null;
        if (inputStream != null) {
            String str = FileUtils.readTextFromStream(inputStream, "UTF-8");
            volume = readPercentFromStr(str);
        }
        if (volume == null) {
            inputStream = process.getErrorStream();
            if (inputStream != null) {
                String str = FileUtils.readTextFromStream(inputStream,"UTF-8");
                volume = readPercentFromStr(str);
            }
        }
        if (volume == null) {
            volume = 73;
        }
        return volume;
    }

    private Integer readPercentFromStr(String str) {
        if (StringUtils.isBlank(str)) {
            return null;
        }
        String[] lines = str.split("\n");
//        Mono: Playback -1727 [80%] [-17.27dB] [on]
        for (String line : lines) {
            while (line.startsWith(" ")) {
                line = line.substring(1);
            }
            if (line.startsWith("Mono:")) {
                Matcher matcher = pattern.matcher(line);
                if (matcher.find()) {
                    String percentStr = line.substring(matcher.start(), matcher.end());
                    return Integer.parseInt(percentStr.substring(1,percentStr.length()-2));
                }
            }
        }
        return null;
    }
}
